<?php

namespace App\V3\V3_2_6\Services;

use App\V3\V3_2_6\Models\CalcExpressMasterModel;
use App\V3\V3_2_6\Models\CalcExpressSlaveModel;
use App\V3\V3_2_6\Models\ExpressTempleteClassModel;
use App\V3\V3_2_6\Models\ExpressTempleteIntervalModel;
use App\V3\V3_2_6\Models\ExpressTempleteModel;
use App\V3\V3_2_6\Models\ExpressTempleteRuleModel;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ExpressTempleteService
{
    //            $arr = [
//                [
//                    'templete_class_name' => '11111',
//                    'templete_class_rule' => [
//                        [
//                            'rule_title' => 'aaaaaa1',
//                            'from_province' => 'aaa',
//                            'from_city' => 'aaa',
//                            'to_province' => 'aaa1',
//                            'to_city' => 'aaa1',
//                            'basic_weight' => 10.2,
//                            'basic_weight_price' => 10.22,
//                            'weight_throw' => 6000,
//                            'price_interval' => [
//                                [
//                                    'min_height' => 0,
//                                    'max_height' => 10,
//                                    'price' => 10
//                                ],
//                                [
//                                    'min_height' => 10,
//                                    'max_height' => 20,
//                                    'price' => 20
//                                ],
//                            ]
//                        ],
//                        [
//                            'rule_title' => 'aaaaaa2',
//                            'from_province' => '',
//                            'from_city' => '',
//                            'to_province' => 'aaa1',
//                            'to_city' => 'aaa1',
//                            'basic_weight' => 10.2,
//                            'basic_weight_price' => 10.22,
//                            'weight_throw' => 6000,
//                            'price_interval' => [
//                                [
//                                    'min_height' => 0,
//                                    'max_height' => 10,
//                                    'price' => 10
//                                ],
//                                [
//                                    'min_height' => 10,
//                                    'max_height' => 20,
//                                    'price' => 20
//                                ],
//                            ]
//                        ]
//                    ]
//                ],
//                [
//                    'templete_class_name' => '22222',
//                    'templete_class_rule' => [
//                        [
//                            'rule_title' => 'bbbbb1',
//                            'from_province' => '',
//                            'from_city' => '',
//                            'to_province' => 'aaa1',
//                            'to_city' => 'aaa1',
//                            'basic_weight' => 10.2,
//                            'basic_weight_price' => 10.22,
//                            'weight_throw' => 6000,
//                            'price_interval' => [
//                                [
//                                    'min_height' => 0,
//                                    'max_height' => 10,
//                                    'cost' => 10
//                                ],
//                                [
//                                    'min_height' => 10,
//                                    'max_height' => 20,
//                                    'price' => 20
//                                ],
//                            ]
//                        ],
//                    ]
//                ]
//            ];
    static public function add($data)
    {
        DB::beginTransaction();

        try {
            if(isset($data['from_city'])) {
                if(!isset($data['from_province'])) {
                    return ['code' => 1, 'msg' => '请选择起始地省份', 'data' => ''];
                }
            }

            $templeteId= ExpressTempleteModel::insertGetId([
                'from_province' => !isset($data['from_province'])?'':$data['from_province'],
                'from_city' => !isset($data['from_city'])?'':$data['from_city'],
                'kuaidi_id' => $data['kuaidi_id'],
                'kuaidi_name' => $data['kuaidi_name'],
                'user_id' => $data['user_id'],
                'main_id' => $data['main_id'],
                'created_at' => time()
            ]);

            if(isset($data['templete_class_info'])) {
                $templeteClassInfo = json_decode($data['templete_class_info'], true);

                foreach($templeteClassInfo as $value) {
                    $expressTempleteId = ExpressTempleteClassModel::insertGetId([
                        'templete_class_name' => $value['templete_class_name'],
                        'express_templete_id' => $templeteId,
                        'created_at' => time()
                    ]);

                    if(!empty($value['templete_class_rule'])) {
                        foreach($value['templete_class_rule'] as $v) {
                            if(!is_numeric($v['basic_weight']) || $v['basic_weight'] < 0) {
                                return ['code' => 1, 'msg' => '首重异常，请核对后重新输入', 'data' => ''];
                            }

                            if(!is_numeric($v['basic_weight_price']) || $v['basic_weight_price'] < 0) {
                                return ['code' => 1, 'msg' => '首重金额异常，请核对后重新输入', 'data' => ''];
                            }

                            if(!is_numeric($v['weight_throw']) || $v['weight_throw'] < 0) {
                                return ['code' => 1, 'msg' => '抛重比异常，请核对后重新输入', 'data' => ''];
                            }

                            $ruleId = ExpressTempleteRuleModel::insertGetId([
                                'rule_title' => !isset($v['rule_title'])?'未命名':$v['rule_title'],
                                'from_province' => !isset($data['from_province'])?'':$data['from_province'],
                                'from_city' => !isset($data['from_city'])?'':$data['from_city'],
                                'to_province' => !isset($v['to_province'])?'':$v['to_province'],
                                'to_city' => !isset($v['to_city'])?'':$v['to_city'],
                                'basic_weight' => $v['basic_weight'],
                                'basic_weight_price' => $v['basic_weight_price'],
                                'weight_throw' => $v['weight_throw'],
                                'templete_class_id' => $expressTempleteId,
                                'express_templete_id' => $templeteId,
                                'user_id' => $data['user_id'],
                                'main_id' => $data['main_id'],
                                'created_at' => time()
                            ]);

                            if(!empty($v['price_interval'])) {
                                foreach($v['price_interval'] as $v1) {
                                    ExpressTempleteIntervalModel::insert([
                                        'min_weight' => !isset($v1['min_weight'])?0:$v1['min_weight'],
                                        'max_weight' => (!isset($v1['max_weight']) || $v1['max_weight'] == 0)?99999999.99:$v1['max_weight'],
                                        'price' => !isset($v1['price'])?0:$v1['price'],
                                        'templete_rule_id' => $ruleId,
                                        'express_templete_id' => $templeteId,
                                        'created_at' => time()
                                    ]);
                                }
                            }
                        }
                    }
                }
            }

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('创建快递模板异常:'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static public function edit($data)
    {
        DB::beginTransaction();

        try {
            //校验起始地省市信息是否缺失
            if(isset($data['from_city'])) {
                if(!isset($data['from_province'])) {
                    return ['code' => 1, 'msg' => '请选择起始地省份', 'data' => ''];
                }
            }

            //更新快递模板信息
            ExpressTempleteModel::where('id', $data['id'])->update([
                'from_province' => !isset($data['from_province'])?'':$data['from_province'],
                'from_city' => !isset($data['from_city'])?'':$data['from_city'],
                'kuaidi_id' => $data['kuaidi_id'],
                'kuaidi_name' => $data['kuaidi_name'],
            ]);

            $templeteInfo = json_decode($data['templete_class_info'], true);

            //软删除旧类目
            ExpressTempleteClassModel::where([
                'express_templete_id' => $data['id'],
            ])
                ->delete();

            //删除旧规则
            ExpressTempleteRuleModel::where([
                'express_templete_id' => $data['id'],
            ])
                ->delete();
            //删除旧区间
            ExpressTempleteIntervalModel::where([
                'express_templete_id' => $data['id'],
            ])
                ->delete();

            foreach($templeteInfo as $key => $value) {
                //重新建立类目以及规则信息
                $expressTempleteId = ExpressTempleteClassModel::insertGetId([
                    'templete_class_name' => $value['templete_class_name'],
                    'express_templete_id' => $data['id'],
                    'created_at' => time()
                ]);

                //重新建立类目以及规则信息
                if(!empty($value['templete_class_rule'])) {
                    foreach($value['templete_class_rule'] as $v) {
                        if(!is_numeric($v['basic_weight']) || $v['basic_weight'] < 0) {
                            return ['code' => 1, 'msg' => '首重异常，请核对后重新输入', 'data' => ''];
                        }

                        if(!is_numeric($v['basic_weight_price']) || $v['basic_weight_price'] < 0) {
                            return ['code' => 1, 'msg' => '首重金额异常，请核对后重新输入', 'data' => ''];
                        }

                        if(!is_numeric($v['weight_throw']) || $v['weight_throw'] < 0) {
                            return ['code' => 1, 'msg' => '抛重比异常，请核对后重新输入', 'data' => ''];
                        }

                        $ruleId = ExpressTempleteRuleModel::insertGetId([
                            'rule_title' => !isset($v['rule_title'])?'未命名':$v['rule_title'],
                            'from_province' => !isset($data['from_province'])?'':$data['from_province'],
                            'from_city' => !isset($data['from_city'])?'':$data['from_city'],
                            'to_province' => !isset($v['to_province'])?'':$v['to_province'],
                            'to_city' => !isset($v['to_city'])?'':$v['to_city'],
                            'basic_weight' => $v['basic_weight'],
                            'basic_weight_price' => $v['basic_weight_price'],
                            'weight_throw' => $v['weight_throw'],
                            'templete_class_id' => $expressTempleteId,
                            'express_templete_id' => $data['id'],
                            'user_id' => $data['user_id'],
                            'main_id' => $data['main_id'],
                            'created_at' => time()
                        ]);

                        if(!empty($v['price_interval'])) {
                            foreach($v['price_interval'] as $v1) {
                                ExpressTempleteIntervalModel::insert([
                                    'min_weight' => !isset($v1['min_weight'])?0:$v1['min_weight'],
                                    'max_weight' => (!isset($v1['max_weight']) || $v1['max_weight'] == 0)?99999999.99:$v1['max_weight'],
                                    'price' => !isset($v1['price'])?0:$v1['price'],
                                    'templete_rule_id' => $ruleId,
                                    'express_templete_id' => $data['id'],
                                    'created_at' => time()
                                ]);
                            }
                        }
                    }
                }
            }

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('编辑快递模板异常:'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static public function list($userId, $isPage, $data)
    {
        $query = ExpressTempleteModel::select(
            'id',
//            'kuaidi_id',
            'kuaidi_name',
            'from_province',
            'from_city',
            'is_top',
        )
            ->with('classInfo', function($query) {
                $query->select(
                    'id',
                    'templete_class_name',
                    'express_templete_id'
                )
                    ->with('ruleInfo', function($query) {
                        $query->select(
                            'id',
                            'rule_title',
                            'to_province',
                            'to_city',
                            'basic_weight',
                            'basic_weight_price',
                            'weight_throw',
                            'templete_class_id'
                        )->with('intervalInfo', function($query) {
                            $query->select(
                                'id',
                                'min_weight',
                                'max_weight',
                                'price',
                                'templete_rule_id'
                            );
                        });
                    });
            })
            ->where($userId)
            ->where('is_del', 0)
            ->orderBy('is_top', 'desc')
            ->orderBy('id', 'desc');

            if($isPage) {
                $query = $query->paginate($data['pageSize'],['*'], '',$data['currentPage']);
            }
            else {
                $query = $query->get()->toArray();
            }

        return $query;
    }

    //置顶
    static public function top($data)
    {
        DB::beginTransaction();

        try {
            $getIsTopInfo = ExpressTempleteModel::where('id', '!=', $data['id'])
                ->where('is_top', 1)->where('is_del', 0)->first();

            $aimInfo = ExpressTempleteModel::where('id', $data['id'])->first();

            if($aimInfo['is_del']) {
                return ['code' => 1, 'msg' => '快递模板不存在，请重试', 'data' => ''];
            }

            if(!empty($getIsTopInfo)) {
                ExpressTempleteModel::where('id', $data['id'])
                    ->lockForUpdate()
                    ->update(['is_top' => 1]);
                ExpressTempleteModel::where('id', $getIsTopInfo['id'])->lockForUpdate()->update(['is_top' => 0]);
            }
            else {
                if(!$aimInfo['is_top']) {
                    ExpressTempleteModel::where('id', $data['id'])
                        ->lockForUpdate()
                        ->update(['is_top' => 1]);
                }
            }

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(\Exception $e) {
            Log::debug('置顶:'.var_export($e->getMessage(), true));
            DB::rollBack();
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //取消置顶快递模板
    static public function cancelTop($data)
    {
        $getIsTopInfo = ExpressTempleteModel::where('id', $data['id'])->first();

        if(!$getIsTopInfo['is_top']) {
            return ['code' => 1, 'msg' => '当前模板未置顶,请重试', 'data' => ''];
        }

        if($getIsTopInfo['is_del']) {
            return ['code' => 1, 'msg' => '当前模板不存在，请重试', 'data' => ''];
        }

        ExpressTempleteModel::where('id', $data['id'])->update(['is_top' => 0]);

        return ['code' => 0, 'msg' => 'success', 'data' => ''];
    }

    //目的地省份城市列表
    static public function termini($userId)
    {
        $provinceInfo = ExpressTempleteRuleModel::select(
            'to_province',
        )
            ->where($userId)
            ->distinct()
            ->get()->toArray();

        $cityInfo = ExpressTempleteRuleModel::select(
            'to_province',
            'to_city'
        )
            ->where($userId)
            ->distinct('to_city')
            ->get()->toArray();

        $arr = [];
        foreach($provinceInfo as $key => $value) {
            $arr[$key]['province_name'] = $value['to_province'];
        }

        foreach($arr as &$val) {
            foreach($cityInfo as $v) {
                if($val['province_name'] == $v['to_province']) {
                    if(!empty($v['to_city'])) {
                        $val['city_info'][] = ['city_name' => $v['to_city']];
                    }
                    else {
                        $val['city_info'] = [];
                    }
                }
            }
        }

        return $arr;
    }

    //新建快递计算结果
    static public function addCalc($data)
    {
        DB::beginTransaction();

        try {
            if(isset($data['from_city'])) {
                if(!isset($data['from_province'])) {
                    return ['code' => 1, 'msg' => '请选择始发地省份', 'data' => ''];
                }
            }

            $masterId = CalcExpressMasterModel::insertGetId([
                'calc_title' => $data['calc_title'],
                'from_province' => !isset($data['from_province'])?'':$data['from_province'],
                'from_city' => !isset($data['from_city'])?'':$data['from_city'],
                'to_province' => !isset($data['to_province'])?'':$data['to_province'],
                'to_city' => !isset($data['to_city'])?'':$data['to_city'],
                'calc_type' => $data['calc_type'],
                'user_id' => $data['user_id'],
                'main_id' => $data['main_id'],
                'created_at' => time(),
            ]);

            $specInfo = json_decode($data['spec_info'], true);

            if($data['calc_type'] == 0 && count($specInfo) > 1) {
                return ['code' => 1, 'msg' => '当前快递类型为一单一件，数量与类型不符，请重试', 'data' => ''];
            }

            foreach($specInfo as $key => &$value) {
                if(!is_numeric($value['length']) || $value['length'] < 0) {
                    return ['code' => 1, 'msg' => '长度仅能为大于0的整数，错误的数据为：'.$value['length'], 'data' => ''];
                }

                if(!is_numeric($value['width']) || $value['width'] < 0) {
                    return ['code' => 1, 'msg' => '宽度仅能为大于0的整数，错误的数据为：'.$value['width'], 'data' => ''];
                }

                if(!is_numeric($value['height']) || $value['height'] < 0) {
                    return ['code' => 1, 'msg' => '高度仅能为大于0的整数，错误的数据为：'.$value['height'], 'data' => ''];
                }

                if(!is_numeric($value['act_weight']) || $value['act_weight'] < 0) {
                    return ['code' => 1, 'msg' => '实际重量仅能为大于0的整数，错误的数据为：'.$value['act_weight'], 'data' => ''];
                }

                $amount = trim($value['amount'], '"');

                if($amount <= 0 || is_float($amount)) {
                    return ['code' => 1, 'msg' => '数量仅能为大于0的整数且不能为小数，错误的数据为：'.$value['amount'], 'data' => ''];
                }

                $value['master_id'] = $masterId;
                $value['created_at'] = time();
            }

            CalcExpressSlaveModel::insert($specInfo);
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => $masterId];
        }
        catch(\Exception $e) {
            Log::debug('保存快递计算结果异常:'.var_export($e->getMessage(), true));
            DB::rollBack();
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //快递模板详细
    static public function detail($id)
    {
        return ExpressTempleteModel::select(
            'id',
            'kuaidi_id',
            'kuaidi_name',
            'from_province',
            'from_city',
            'is_top',
        )
            ->with('classInfo', function($query) {
                $query->select(
                    'id',
                    'templete_class_name',
                    'express_templete_id'
                )
                    ->with('ruleInfo', function($query) {
                        $query->select(
                            'id',
                            'rule_title',
                            'to_province',
                            'to_city',
                            'basic_weight',
                            'basic_weight_price',
                            'weight_throw',
                            'templete_class_id'
                        )->with('intervalInfo', function($query) {
                            $query->select(
                                'id',
                                'min_weight',
                                'max_weight',
                                'price',
                                'templete_rule_id'
                            );
                        });
                    });
            })
            ->where('id', $id)
            ->where('is_del', 0)
            ->first();
    }

    //修改快递计算结果
    static public function editCalc($data)
    {
        DB::beginTransaction();

        try {
            if (isset($data['from_city'])) {
                if (!isset($data['from_province'])) {
                    return ['code' => 1, 'msg' => '请选择始发地省份', 'data' => ''];
                }
            }

            $calcInfo = CalcExpressMasterModel::where([
                'id' => $data['id'],
                'is_del' => 0
            ])->first();

            if(empty($calcInfo)) {
                return ['code' => 1, 'msg' => '快递计算结果不存在，请重试', 'data' => ''];
            }

            CalcExpressMasterModel::where('id', $data['id'])->update([
                'calc_title' => $data['calc_title'],
                'from_province' => !isset($data['from_province'])?'':$data['from_province'],
                'from_city' => !isset($data['from_city'])?'':$data['from_city'],
                'to_province' => !isset($data['to_province'])?'':$data['to_province'],
                'to_city' => !isset($data['to_city'])?'':$data['to_city'],
                'calc_type' => $data['calc_type'],
            ]);

            CalcExpressSlaveModel::where('master_id', $data['id'])->delete();

            $specInfo = json_decode($data['spec_info'], true);

            if($data['calc_type'] == 0 && count($specInfo) > 1) {
                return ['code' => 1, 'msg' => '当前快递类型为一单一件，数量与类型不符，请重试', 'data' => ''];
            }

            foreach($specInfo as $key => &$value) {
                if(!is_numeric($value['length']) || $value['length'] < 0) {
                    return ['code' => 1, 'msg' => '长度仅能为大于0的整数，错误的数据为：'.$value['length'], 'data' => ''];
                }

                if(!is_numeric($value['width']) || $value['width'] < 0) {
                    return ['code' => 1, 'msg' => '宽度仅能为大于0的整数，错误的数据为：'.$value['width'], 'data' => ''];
                }

                if(!is_numeric($value['height']) || $value['height'] < 0) {
                    return ['code' => 1, 'msg' => '高度仅能为大于0的整数，错误的数据为：'.$value['height'], 'data' => ''];
                }

                if(!is_numeric($value['act_weight']) || $value['act_weight'] < 0) {
                    return ['code' => 1, 'msg' => '实际重量仅能为大于0的整数，错误的数据为：'.$value['act_weight'], 'data' => ''];
                }

                if(!is_integer($value['amount']) || $value['amount'] < 0) {
                    return ['code' => 1, 'msg' => '数量仅能为大于0的整数且不能为小数，错误的数据为：'.$value['amount'], 'data' => ''];
                }

                $value['master_id'] = $data['id'];
                $value['created_at'] = time();
            }

            CalcExpressSlaveModel::insert($specInfo);
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(\Exception $e) {
            Log::debug('保存快递计算结果异常:'.var_export($e->getMessage(), true));
            DB::rollBack();
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //快递计算结果列表
    static public function listCalc($userId)
    {
        $result = CalcExpressMasterModel::select(
            'id',
            'calc_title',
            'from_province',
            'from_city',
            'to_province',
            'to_city',
            'calc_type',
            'created_at'
        )
            ->where([
                'is_del' => 0,
            ])
            ->where($userId)
            ->orderBy('id', 'desc')
            ->get()->toArray();

        foreach($result as &$value) {
            $slaveInfo = CalcExpressSlaveModel::selectRaw(
                'sum(amount) as total_amount'
            )
                ->where('master_id', $value['id'])->first();

            $value['total_amount'] = $slaveInfo['total_amount'];
        }

        return $result;
    }

    //快递计算结果详细
    static public function detailCalc($id)
    {
        return CalcExpressMasterModel::select(
            'id',
            'calc_title',
            'from_province',
            'from_city',
            'to_province',
            'to_city',
            'calc_type',
        )
            ->with('specInfo', function($query) {
                $query->select(
                    'id',
                    'master_id',
                    'length',
                    'width',
                    'height',
                    'act_weight',
                    'amount',
                );
            })
            ->where([
                'id' => $id,
                'is_del' => 0
            ])->first();
    }

    //计算结果
    static public function calc($data, $userId)
    {
        if(isset($data['id'])) {//从保存的结果中进行结算
            $result = self::getCalcResultFromHistory($data, $userId);
        }
        else {
            //直接计算获得-未保存结果
            $result = self::getCalcResultByDirectly($data, $userId);
        }

        //排序
        $finalResult = self::sortResult($data['sort'], $result);

        return ['code' => 0, 'msg' => 'success', 'data' => $finalResult];
    }

    //直接计算获取结果
    static private function getCalcResultByDirectly($data, $userId)
    {
        $slaveInfo = json_decode($data['spec_info'], true);

        $condition = [];

        if(!empty($data['from_province'])) {
            $condition['a.from_province'] = ['EQ' => $data['from_province']];
        }

        if(!empty($data['from_city'])) {
            $condition['a.from_city'] = ['EQ' => $data['from_city']];
        }

        if(!empty($data['to_province'])) {
            $condition['to_province'] = ['EQ' => $data['to_province']];
        }

        if(!empty($data['to_city'])) {
            $condition['to_city'] = ['EQ' => $data['to_city']];
        }

        $sumVolumeWeight = 0;
        $sumAmount = 0;
        $sumActulWeight = 0;
        foreach($slaveInfo as $value) {
            $sumVolumeWeight += $value['length'] * $value['width'] * $value['height'];
            $sumAmount += $value['amount'];
            $sumActulWeight += $value['act_weight'];
        }

        $arr = [
            'sum_volume_weight' => $sumVolumeWeight,
            'sum_actul_weight' => $sumActulWeight,
            'sum_amount' => $sumAmount,
            'total_amount_weight' => $sumActulWeight * $sumAmount
        ];

        return self::commonCalc($data, $arr, $condition, $userId);
    }

    //从保存的结果中进行结算
    static private function getCalcResultFromHistory($data, $userId)
    {
        $masterInfo = CalcExpressMasterModel::where([
            'id' => $data['id'],
            'is_del' => 0
        ])->first();

        if(empty($masterInfo)) {
            return ['code' => 1, 'msg' => '您要计算的内容不存在', 'data' => ''];
        }

        $slaveInfo = CalcExpressSlaveModel::where('master_id', $data['id'])->get()->toArray();

        $condition = [];

        if(!empty($masterInfo['from_province'])) {
            $condition['a.from_province'] = ['EQ' => $masterInfo['from_province']];
        }

        if(!empty($masterInfo['from_city'])) {
            $condition['a.from_city'] = ['EQ' => $masterInfo['from_city']];
        }

        if(!empty($masterInfo['to_province'])) {
            $condition['to_province'] = ['EQ' => $masterInfo['to_province']];
        }

        if(!empty($masterInfo['to_city'])) {
            $condition['to_city'] = ['EQ' => $masterInfo['to_city']];
        }

        $sumVolumeWeight = 0;
        $sumAmount = 0;
        $sumActulWeight = 0;
        foreach($slaveInfo as $value) {
            $sumVolumeWeight += $value['length'] * $value['width'] * $value['height'];
            $sumAmount += $value['amount'];
            $sumActulWeight += $value['act_weight'];
        }

        $arr = [
            'sum_volume_weight' => $sumVolumeWeight,
            'sum_actul_weight' => $sumActulWeight,
            'sum_amount' => $sumAmount,
            'total_amount_weight' => $sumActulWeight * $sumAmount
        ];

        return self::commonCalc($data, $arr, $condition, $userId);
    }

    static private function commonCalc($data, $arr, $condition, $userId)
    {
        //寻找符合始发地和目的地的规则
        $ruleInfo = ExpressTempleteRuleModel::select(
            'a.*',
            'b.templete_class_name',
            'c.kuaidi_id',
            'c.kuaidi_name'
        )
            ->from('express_templete_rule as a')
            ->leftJoin('express_templete_class as b', 'b.id', '=', 'a.templete_class_id')
            ->leftJoin('express_templete as c', 'c.id', '=', 'b.express_templete_id')
            ->where($condition)
            ->where($userId);

        if($data['kuaidi_id'] > 0) {
            $ruleInfo->where('c.kuaidi_id', $data['kuaidi_id']);
        }

        $ruleInfo = $ruleInfo->get()->toArray();

        if(!empty($ruleInfo)) {
            foreach($ruleInfo as $key => $val) {
                $volumeWeight = number_format(($arr['sum_volume_weight'] / (intval($val['weight_throw']) * $arr['sum_amount'])),2, '.', '');

                $result = self::findPrice($val['id'], $volumeWeight, $val);
                $arr['rule_info'][$key] = [
                    'templete_class_name' => $val['templete_class_name'],
                    'info' => [
                        'id' => $val['id'],
                        'weight_throw' => $val['weight_throw'],
                        'kuaidi_id' => $val['kuaidi_id'],
                        'kuaidi_name' => $val['kuaidi_name'],
                        'to_province' => $val['to_province'],
                        'to_city' => $val['to_city'],
                        'volume_weight' => $volumeWeight,
                        'actual_weight' => $arr['total_amount_weight'],
                        'interval_info' =>  empty($result)?'':self::findPrice($val['id'], $volumeWeight, $val),
                        'actul_weight_info' => empty(self::findPrice($val['id'], $arr['total_amount_weight'], $val))?'':self::findPrice($val['id'], $arr['total_amount_weight'], $val)
                    ]
                ];
            }
        }
        else {
            $arr['rule_info'] = [];
        }

        return $arr;
    }

    //匹配区间规则
    static public function findPrice($ruleId, $volumeWeight, $value)
    {
        if($volumeWeight <= $value['basic_weight']) {
            return [
                'min_weight' => 0,
                'max_weight' => $value['basic_weight'],
                'price' => empty($value['basic_weight_price'])?'':$value['basic_weight_price']
            ];
        }
        else {
            $intervalInfo = ExpressTempleteIntervalModel::where('templete_rule_id', $ruleId)->get()->toArray();

            foreach($intervalInfo as $val) {
                if($volumeWeight >= $val['min_weight'] && $volumeWeight < $val['max_weight']) {
                    return [
                        'min_weight' => $val['min_weight'],
                        'max_weight' => $val['max_weight'],
                        'price' => ($val['price'] + $value['basic_weight_price'])
                    ];
                }
            }
        }
    }

    //排序公共方法
    static private function sortResult($sort, $data)
    {
        $arr = [];

        if(empty($data['rule_info'])) {
            return $data;
        }

        $tempIntervalPrice = 0;//临时抛重金额
        $tempActulPrice = 0;//临时实际重量金额
        $i = 0;
        foreach($data['rule_info'] as $key => $value) {

            if($value['info']['interval_info'] == '') {
                $tempIntervalPrice = 0;
            }
            else {
                $tempIntervalPrice = $value['info']['interval_info']['price'];
            }

            if($value['info']['actul_weight_info'] == '') {
                $tempActulPrice = 0;
            }
            else {
                $tempActulPrice = $value['info']['actul_weight_info']['price'];
            }

            if($sort) {
                if($tempIntervalPrice > $tempActulPrice) {

                    $arr[$i] = [
                        'id' => $value['info']['id'],
                        'price' => $tempIntervalPrice,
                    ];
                }
                else {
                    $arr[$i] = [
                        'id' => $value['info']['id'],
                        'price' => $tempIntervalPrice,
                    ];
                }
            }
            else {
                if($tempIntervalPrice < $tempActulPrice) {

                    $arr[$i] = [
                        'id' => $value['info']['id'],
                        'price' => $tempIntervalPrice,
                    ];
                }
                else {
                    $arr[$i] = [
                        'id' => $value['info']['id'],
                        'price' => $tempIntervalPrice,
                    ];
                }
            }

            $i++;
        }

        if($sort) {
            $result = self::sortUp($arr);
        }
        else {
            $result = self::sortDown($arr);
        }

        $newArr['sum_volume_weight'] = $data['sum_volume_weight'];
        $newArr['sum_actul_weight'] = $data['sum_actul_weight'];
        $newArr['sum_amount'] = $data['sum_amount'];
        $newArr['total_amount_weight'] = $data['total_amount_weight'];
        $newArr['rule_info'] = [];

        foreach($result as $v1) {
            foreach($data['rule_info'] as $v2) {
                if($v1['id'] == $v2['info']['id']) {
                    $newArr['rule_info'][] = $v2;
                }
            }
        }
        return $newArr;
    }

    //升序
    static private function sortUp($arr)
    {
        //二维数组排序
        usort($arr, function($a, $b) {
            if($a['price'] == $b['price'])
                return 0;

            return ($a['price'] < $b['price'])?-1:1;
        });

        return $arr;
    }

    //降序
    static private function sortDown($arr)
    {
        //二维数组排序
        usort($arr, function($a, $b) {
            if($a['price'] == $b['price'])
                return 0;

            return ($a['price'] > $b['price'])?-1:1;
        });

        return $arr;
    }


    static public function kdList($condition)
    {
        $result = ExpressTempleteModel::select(
            'et.id as et_id',
            'etr.id as kd_id',
            'kuaidi_name',
            'weight_throw',
            'et.from_province',
            'et.from_city',
            'to_province',
            'to_city',
            'basic_weight_price',
            'total_weight',
            'basic_weight'
            )
        ->from('express_templete as et')
        ->leftJoin('express_templete_rule as etr','etr.express_templete_id','=','et.id')
        ->where('et.is_del', 0)
        ->where($condition)
        ->orderBy('etr.id', 'desc')
        ->get()->toArray();

            return $result;
    }
}
